﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PlaceHR.Processor.Processor
{
    public abstract class ProcessorBase<T, S> : IProcessor<T, S> where T : IProcessorContext
    {

        public virtual string ProcessorTypeCode
        {
            get;
            protected set;
        }

        public virtual T CurrentContext
        {
            get;
            protected set;
        }

        public virtual S CurrentEntity
        {
            get;
            protected set;
        }

        public virtual bool IsValidForProcess
        {
            get;
            protected set;
        }

        private Dictionary<int, IStepCalculator<T, S>> StepCalculators
        {
            get;
            set;
        }

        public virtual void Init(Employee employee, IEngine currentEngine)
        {
            this.CurrentContext = this.LoadCurrentContext(employee, currentEngine);
            this.CurrentEntity = this.LoadCurrentEntity(employee, currentEngine);

            if (this.StepCalculators == null)
            {
                StepCalculators = new Dictionary<int, IStepCalculator<T, S>>();
            }
            else
            {
                this.StepCalculators.Clear();
            }

            this.RegisterStepCalculators();
        }

        public virtual void Register(IStepCalculator<T, S> step)
        {
            int key = 1;
            if (this.StepCalculators.Keys != null && this.StepCalculators.Keys.Count > 0)
            {
                key = this.StepCalculators.Keys.Max() + 1;
            }

            this.StepCalculators.Add(key, step);
        }

        public virtual void Process()
        {
            if (!this.IsValidForProcess)
            {
                Console.WriteLine(string.Format("IsValidForProcess = False, 针对{0}员工的计算已退出！", CurrentContext.CurrentEmployee.EmployeeID));
                return;
            }

            Console.WriteLine(string.Format("{0}员工数据开始计算...", CurrentContext.CurrentEmployee.EmployeeID));
            if (this.StepCalculators.Count > 0)
            {
                for (int i = 1; i <= this.StepCalculators.Count; i++)
                {
                    if (this.StepCalculators[i] != null)
                    {
                        this.StepCalculators[i].Calculate(this.CurrentContext, this.CurrentEntity);
                    }
                }
            }
            Console.WriteLine(string.Format("{0}员工数据计算完毕！", CurrentContext.CurrentEmployee.EmployeeID));
        }

        protected abstract T LoadCurrentContext(Employee employee, IEngine currentEngine);

        protected abstract S LoadCurrentEntity(Employee employee, IEngine currentEngine);

        protected abstract void RegisterStepCalculators();
    }
}
